package com.example.miniomultipartupload.common.util;

/**
 * @description:
 * @author: konglingdi
 * @date: 2021/11/29 16:13
 */

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * @version v1.0
 * @description: {单文件切割 、碎片文件合并}
 * @author: admin
 */
public class SplitMergeFileUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(SplitMergeFileUtil.class);
    /**
     * @param targetFileName   目标文件路径
     * @param saveDir      存放的目录
     * @param saveFileName 生成文件的前缀名
     * @param suffix       生成文件的后缀名
     * @param splitSize    每一个文件 多少行数据
     */
    public static void splitFile(String targetFileName, String saveDir, String saveFileName, String suffix, long splitSize) throws Exception {
        if (!saveDir.endsWith("\\")) {
            saveDir += File.separator;
        }
        File saveDirFile=new File(saveDir);
        if(!saveDirFile.exists()){
            saveDirFile.mkdirs();
        }
        File targetFile = new File(targetFileName);
        if (!targetFile.exists()) {
            throw new Exception("目标路径：[ " + targetFileName + " ] 有错误...");
        }
        //输入缓冲流
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(targetFileName), StandardCharsets.UTF_8));
        String str = null;
        //行数
        long len = 0;
        System.out.println("开始写入......请等待......");
        long startTime = System.currentTimeMillis();
        //输出缓冲流
        BufferedWriter writer = null;
        while ((str = reader.readLine()) != null) {
            //当前行文件
            long txtSize = (len/splitSize) + 1;
            String fileName = saveDir + saveFileName + txtSize + "." + suffix;
            //使用BufferedWriter如果 不进行 flush或者close 写入不了内容。
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName, true)));
            writer.write(str + System.lineSeparator());
            writer.flush();
            len++;
        }
        assert writer != null;
        writer.close();
        reader.close();
    }

    /**
     * 切割指定源文件
     * @param srcFile      指定要切割的源文件
     * @param outputDir   指定输出目录
     * @param size        切割大小
     * @param prefix       件名前缀
     * @param suffix       文件名后缀
     * @param
     * @throws IOException 有异常时抛出，由调用者处理
     */
    public static void split(File srcFile, String outputDir,String prefix, String suffix, int size) throws IOException {
        File  outFile=new File(outputDir);
        if(!outFile.exists()){
            outFile.mkdirs();
        }
        try (FileInputStream inputStream = FileUtils.openInputStream(srcFile);) {
            byte[] buffer = new byte[size];
            int len = 0;
            for (int i = 0; (len = IOUtils.read(inputStream, buffer)) > 0; i++) {
                String  fileName=suffix+i+"."+suffix;
                LOGGER.info("开始执行切割文件fileName="+fileName);
                File temp = FileUtils.getFile(outputDir, fileName);
                FileUtils.writeByteArrayToFile(temp, buffer, 0, len);
                LOGGER.info("结束执行切割文件fileName="+fileName);
            }
        }
    }


    /**
     * 合并文件
     * @param inputDir 碎片输入目录
     * @param destDir  合并目标文件目录
     * @param destName   合并后文件名称
     * @throws IOException 有异常时抛出，由调用者处理
     */
    public static void  combine(String inputDir, String  destDir,String destName ) throws IOException {
        File  destDirFile=new File(destDir);
        if(!destDirFile.exists()){
            destDirFile.mkdirs();
        }
        File inputPath = FileUtils.getFile(inputDir);
        String[] files = inputPath.list();
        try (FileOutputStream outputStream = FileUtils.openOutputStream(new File(destDir+destName))) {
            // 按文件名排序
            assert files != null;
            Arrays.sort(files);
            for (String fileName : files) {
                LOGGER.info("combineFormChips遍历指定目录的文件fileName="+fileName);
                File file = FileUtils.getFile(inputPath, fileName);
                byte[] data = FileUtils.readFileToByteArray(file);
                IOUtils.write(data, outputStream);
            }
        } catch (Exception e) {
            LOGGER.info("合并文件异常{}" + e.toString());
        }
    }



    public    static   void  main(String[]  args){
        try {
            split(new File("C:\\Users\\15516\\Desktop\\三维\\地宫凤纹金棺补拍(1).zip"),"C:\\Users\\15516\\Desktop\\三维\\qiege","b","split",10*1024*1024);
            // combine("D:/download/nio/","D:/download/comnio/","combineNewNio.avi");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
